package com.gupaoedu.vip;

import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Map;

/**
 * @Author: JLL
 * @Date: 2019/6/17 21:14
 */
public class ProcessorHandler implements Runnable{

    private Socket socket;
//    private Object service;
    private Map<String,Object> handlerMap;

    public ProcessorHandler(Socket socket, Map<String,Object> handlerMap) {
        this.socket = socket;
        this.handlerMap = handlerMap;
    }

    @Override
    public void run() {
        //这里应该要处理流问题
        ObjectInputStream  objectInputStream =  null;
        ObjectOutputStream objectOutputStream = null;
        //输入流中要有哪些东西？   类、方法名、参数
        //这里要反序列化，然后反射调用方法
        try {
            objectInputStream = new ObjectInputStream(socket.getInputStream());
            //反序列化
            RpcRequest rpcRequest = (RpcRequest)objectInputStream.readObject();
            Object result = invoke(rpcRequest);

            //反射得到结果，再写出去。。。
            objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            objectOutputStream.writeObject(result);
            objectOutputStream.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }finally {
            if(objectOutputStream!=null){
                try {
                    objectOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(objectInputStream!=null){
                try {
                    objectInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private Object invoke(RpcRequest rpcRequest) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        String serviceName = rpcRequest.getClassName();
        String version = rpcRequest.getVersion();
        //
        if(!StringUtils.isEmpty(version)){
            serviceName += "-" + version;
        }

        Object service = handlerMap.get(serviceName);

        if(service == null){
            throw new RuntimeException("service not found " + serviceName);
        }

        Object[] args = rpcRequest.getParameters();
        Method method = null;
        if(args!=null){
            Class[] types = new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                types[i] = args[i].getClass();
            }
            Class clazz = Class.forName(rpcRequest.getClassName());
            method = clazz.getMethod(rpcRequest.getMethodName(),types); //clazz.getMethod的第二个参数、是类类型
        }else {
            Class clazz = Class.forName(rpcRequest.getClassName());
            method = clazz.getMethod(rpcRequest.getMethodName());
        }

        Object result = method.invoke(service,args);  //注意invoke第二个参数、是实参
        return result;
    }


}
